﻿/**********************************************************
 ●项目：Smartkernel
 ●公司：智能核心信息技术研发中心
 ●作者：曹艳白
 ●邮箱：caoyanbai@gmail.com
 ●创建：2008-08-10
**********************************************************/
using System;
using System.Collections.Generic;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;

namespace Smartkernel.Net
{
    /// <summary>
    /// 网络操作相关功能
    /// </summary>
    public static class SmartNet
    {
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="address">文件的Uri路径</param>
        /// <param name="fileName">本地路径</param>
        public static void Download(string address, string fileName)
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.DownloadFile(address, fileName);
            }
        }
        /// <summary>
        /// 获得本机MAC地址
        /// </summary>
        /// <returns>MAC地址</returns>
        public static string GetHostMAC()
        {
            string mac = "";
            using (ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapterConfiguration"))
            {
                using (ManagementObjectCollection managementObjectCollection = managementClass.GetInstances())
                {
                    foreach (ManagementObject managementObject in managementObjectCollection)
                    {
                        if (managementObject["IPEnabled"].ToString() == "True")
                        {
                            mac = managementObject["MacAddress"].ToString();
                            break;
                        }
                        managementObject.Dispose();
                    }
                }
            }
            return mac;
        }
        /// <summary>
        /// 通过主机名获得IP地址
        /// </summary>
        /// <param name="hostName">主机名，例如：localhost,www.Smartkernel.com</param>
        /// <returns>IP地址列表</returns>
        public static List<string> GetIPByHostName(string hostName)
        {
            List<string> ips = new List<string>();
            IPHostEntry ipHostEntry = Dns.GetHostEntry(hostName);
            if (ipHostEntry.AddressList.Length > 0)
            {
                for (int i = 0; i < ipHostEntry.AddressList.Length; i++)
                {
                    ips.Add((ipHostEntry.AddressList)[i].ToString());
                }
            }
            return ips;
        }
        /// <summary>
        /// 获得本地主机的名称
        /// </summary>
        /// <returns>主机名</returns>
        public static string GetHostName()
        {
            return Dns.GetHostName();
        }
        /// <summary>
        /// 获得Uri的响应Html
        /// </summary>
        /// <param name="address">Uri地址</param>
        /// <param name="encoding">字符编码</param>
        /// <returns>响应的Html</returns>
        public static string GetHtml(string address, Encoding encoding)
        {
            WebClient webClient = new WebClient();
            webClient.Encoding = encoding;
            return webClient.DownloadString(address);
        }
        /// <summary>
        /// 检查端口状态，是否启用TCP监听
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口</param>
        /// <returns>状态</returns>
        public static bool CheckPort(string ip, int port)
        {
            IPAddress ipAddress = IPAddress.Parse(ip);
            IPEndPoint ipEndPoint = new System.Net.IPEndPoint(ipAddress, port);
            bool isListening = false;
            Socket sSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                sSocket.Connect(ipEndPoint);
                sSocket.Close();
                isListening = true;
            }
            catch
            {

            }
            return isListening;
        }
        /// <summary>
        /// 解析Uri获得域名
        /// </summary>
        /// <param name="uri">待解析的Uri</param>
        /// <param name="domainType">期望解析的类型（域名或子域名）</param>
        /// <param name="domain">解析的域名</param>
        /// <returns>解析的情况</returns>
        public static SmartDomainParseType GetDomain(string uri, SmartDomainType domainType, out string domain)
        {
            Uri fullUri = new Uri(uri.ToLower());
            SmartDomainParseType domainParseType;
            domain = uri;
            if (fullUri.IsFile == true)
            {
                domainParseType = SmartDomainParseType.FilePath;
            }
            else
            {
                if (fullUri.IsWellFormedOriginalString() == true)
                {
                    int index = fullUri.Authority.IndexOf('.', 0);
                    switch (domainType)
                    {
                        case SmartDomainType.Domain:
                            domain = fullUri.Authority.Substring(index + 1, fullUri.Authority.Length - index - 1);
                            break;
                        case SmartDomainType.SubDomain:
                            domain = fullUri.Authority;
                            break;
                    }
                    domainParseType = SmartDomainParseType.Uri;
                }
                else
                {
                    domainParseType = SmartDomainParseType.UnKnown;
                }
            }
            return domainParseType;
        }
        /// <summary>
        /// 比较IP地址的大小
        /// </summary>
        /// <param name="sourceIP">第一个IP</param>
        /// <param name="destinationIP">第二个IP</param>
        /// <returns>如果第一个大于第二个返回-1，如果第一个小于第二个返回1</returns>
        public static int CompareIP(string sourceIP, string destinationIP)
        {
            IPAddress source = IPAddress.Parse(sourceIP);
            IPAddress destination = IPAddress.Parse(destinationIP);
            byte[] sourceIPBytes = source.GetAddressBytes();
            byte[] destinationIPBytes = destination.GetAddressBytes();

            // IPv4 and IPv6
            if (sourceIPBytes.Length < destinationIPBytes.Length)
            {
                return 1;
            }
            // IPv6 and IPv4
            else if (sourceIPBytes.Length > destinationIPBytes.Length)
            {
                return -1;
            }
            // IPv4 and IPv4 OR IPv6 and IPv6
            else
            {
                for (int i = 0; i < sourceIPBytes.Length; i++)
                {
                    if (sourceIPBytes[i] < destinationIPBytes[i])
                    {
                        return 1;
                    }
                    else if (sourceIPBytes[i] > destinationIPBytes[i])
                    {
                        return -1;
                    }
                }

                return 0;
            }
        }
        /// <summary>
        /// 是否是私有IP
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <returns>是否是私有IP</returns>
        public static bool IsPrivateIP(string ip)
        {
            IPAddress ipAddress = IPAddress.Parse(ip);
            if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                byte[] ipBytes = ipAddress.GetAddressBytes();
                if (ipBytes[0] == 192 && ipBytes[1] == 168)
                {
                    return true;
                }
                if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
                {
                    return true;
                }
                if (ipBytes[0] == 10)
                {
                    return true;
                }
                if (ipBytes[0] == 169 && ipBytes[1] == 254)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 下载网页并保存成.mht格式的文件
        /// </summary>
        /// <param name="url">网页地址：例如，http://www.Smartkernel.com/index.aspx</param>
        /// <param name="localPath">存放的路径：例如，D:\index.mht</param>
        public static void DownloadToMHT(string url, string localPath)
        {
            //CDO.MessageClass messageClass = new CDO.MessageClass();
            //messageClass.CreateMHTMLBody(url, CDO.CdoMHTMLFlags.cdoSuppressNone, "", "");
            //ADODB.Stream stream = null;
            //try
            //{
            //    stream = messageClass.GetStream();
            //    stream.SaveToFile(localPath, ADODB.SaveOptionsEnum.adSaveCreateOverWrite);
            //}
            //finally
            //{
            //    stream.Close();
            //}
        }
        /// <summary>
        /// 检查本地计算机是否联网
        /// </summary>
        /// <returns>true＝已联网，false＝未联网</returns>
        public static bool IsOnLine()
        {
            SmartConnectionState state = 0;
            SmartWin32API.InternetGetConnectedState(ref state, 0);
            if (((int)SmartConnectionState.Offline & (int)state) != 0)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// Ping目标计算机
        /// </summary>
        /// <param name="targetMachine">目标计算机的IP（211.66.4.102）或者主机名（SmartKernel-PC）</param>
        /// <returns>IPStatus枚举</returns>
        public static IPStatus Ping(string targetMachine)
        {
            IPAddress ip = Dns.GetHostEntry(targetMachine).AddressList[0];
            PingOptions options = new PingOptions(128, true);
            Ping ping = new Ping();
            byte[] data = new byte[32];
            List<long> responseTimes = new List<long>();
            PingReply reply = ping.Send(ip, 1000, data, options);
            if (reply != null)
            {
                return reply.Status;
            }
            else
            {
                return IPStatus.Unknown;
            }
        }
        /// <summary>
        ///  检查网址是否可以访问
        /// </summary>
        /// <param name="url">测试的网址地址：例如，http://www.Smartkernel.com</param>
        /// <param name="timeOut">设置超时时间，在指定的时间内无响应的认为是无法访问，单位为秒</param>
        /// <returns>true＝可以访问，false＝不可以访问</returns>
        public static bool IsCanVisit(string url, int timeOut)
        {
            url = "http://" + url.Replace("http://", "");
            try
            {
                HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                httpWebRequest.AllowAutoRedirect = false;
                httpWebRequest.Timeout = timeOut;
                httpWebRequest.Method = "HEAD";
                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                try
                {
                    if (httpWebResponse.StatusCode == HttpStatusCode.OK)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                finally
                {
                    httpWebResponse.Close();
                }
            }
            catch
            {
                return false;
            }
        }
    }
}
